import pandas as pd
import numpy as np
from scipy.stats import norm
import statsmodels.api as sm

def topsis_ranking(df, weight_series, output_path, num_levels=4):
    indicators = weight_series.index.tolist()
    matrix = df[indicators].values
    norm_matrix = matrix / np.sqrt((matrix ** 2).sum(axis=0))
    weighted = norm_matrix * weight_series.values
    ideal = weighted.max(axis=0)
    anti_ideal = weighted.min(axis=0)
    dist_pos = np.sqrt(((weighted - ideal) ** 2).sum(axis=1))
    dist_neg = np.sqrt(((weighted - anti_ideal) ** 2).sum(axis=1))
    df['相对接近度C'] = dist_neg / (dist_pos + dist_neg)
    df['C排名'] = df['相对接近度C'].rank(ascending=False, method='min')

    # ✅ 增加年度内排名
    if '年份' in df.columns:
        df['年度排名'] = df.groupby('年份')['C排名'].rank(method='min')

    # ✅ Probit 分档
    epsilon = 1e-10
    df['C值'] = df['相对接近度C'].clip(epsilon, 1 - epsilon)
    df['Probit值'] = norm.ppf(df['C值'])
    X = sm.add_constant(df['Probit值'])
    model = sm.OLS(df['C值'], X).fit()
    df['C拟合值'] = model.predict(X)

    if num_levels == 3:
        probs = [1/3, 2/3]
    elif num_levels == 4:
        probs = [0.25, 0.5, 0.75]
    elif num_levels == 5:
        probs = [0.2, 0.4, 0.6, 0.8]
    else:
        raise ValueError("Only 3/4/5 levels supported")

    probit_values = [norm.ppf(p) for p in probs]
    cut_points = model.params['const'] + model.params['Probit值'] * np.array(probit_values)
    df['分档等级'] = pd.cut(df['C拟合值'],
                            bins=[-np.inf] + list(cut_points) + [np.inf],
                            labels=[str(i) for i in range(1, num_levels + 1)])

    df.to_csv(output_path, index=False, encoding='utf-8-sig')
    return df, cut_points.tolist(), model.summary().as_text()
